// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	2/21/2015 12:56:03 AM				
// -----------------------------

#include "ShaderManager.h"

#include "Engine.h"
#include "FileManager.h"
#include "FilePackage.h"

#include "PlatformProvider.h"

#include "IVertexShader.h"
#include "IPixelShader.h"
#include "IInputLayout.h"

#include "ShaderLoader.h"

namespace Flow
{

	ShaderManager::ShaderManager(IGraphicsDevice* lpDevice, IMutex* lpGraphicsMutex)
		: m_lpGraphicsDevice(lpDevice)
		, m_lpGraphicsMutex(lpGraphicsMutex)
	{
	}

	ShaderManager::~ShaderManager()
	{
		for (auto pair : m_Shaders)
			pair.second->Release();
		for (auto pair : m_InputLayouts)
			pair.second->Release();
	}


	IShader* ShaderManager::LoadShader(const tstring& file, ShaderType::Enum type)
	{
		if (m_Shaders.count(file) > 0)
			return m_Shaders.at(file);

		ShaderLoader* lpLoader = new ShaderLoader(m_lpGraphicsDevice, m_lpGraphicsMutex, file, type);
		IVertexShader* lpShader = static_cast<IVertexShader*>(lpLoader->Load());
		m_Shaders.insert(make_pair(file, lpShader));

		return lpShader;
	}
	IShader* ShaderManager::GetShader(const tstring& file, ShaderType::Enum type, Bool loadIfNotFound)
	{
		if (m_Shaders.count(file) < 1)
		{
			if (loadIfNotFound)
				return LoadShader(file, type);
		}
		else
			return m_Shaders.at(file);

		return nullptr;
	}

	IInputLayout* ShaderManager::LoadInputLayout(UInt32 inputLayout)
	{
		if (m_InputLayouts.count(inputLayout) > 0)
			return m_InputLayouts.at(inputLayout);

		IInputLayout* lpInputLayout = PlatformProvider::QueryInterface<IInputLayout>("InputLayout");


		m_InputLayouts.insert(make_pair(inputLayout, lpInputLayout));

		return lpInputLayout;
	}
	IInputLayout* ShaderManager::GetInputLayout(UInt32 inputLayout, Bool loadIfNotFound)
	{
		if (m_InputLayouts.count(inputLayout) < 1)
		{
			if (loadIfNotFound)
				return LoadInputLayout(inputLayout);
		}
		else
			return m_InputLayouts.at(inputLayout);

		return nullptr;
	}
	

}